package com.ncf.rpc.common;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.objenesis.Objenesis;
import org.objenesis.ObjenesisStd;
import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.ProtostuffIOUtil;
import com.dyuproject.protostuff.Schema;
import com.dyuproject.protostuff.runtime.RuntimeSchema;

/**
 * 序列化工具（基于Protostuff实现）
 * @author crazy
 *
 */
public class SerializationUtil {

	private static Map<Class<?>,Schema<?>> cacheSchema = new ConcurrentHashMap<Class<?>,Schema<?>>();
	
	private static Objenesis objenesis = new ObjenesisStd(true);
	
	private  SerializationUtil(){}
	
	/**
	 * 获取类的schema
	 * @param cls
	 * @return
	 */
	private static <T> Schema<T> getSchema(Class<T> cls) {
		@SuppressWarnings("unchecked")
		Schema<T> schema = (Schema<T>) cacheSchema.get(cls);
		if (schema == null) {
			schema = RuntimeSchema.createFrom(cls);
			if(schema != null) {
				cacheSchema.put(cls, schema);
			}
		}
		return schema;
	}
	
	@SuppressWarnings("unchecked")
	public static <T> byte[] serialize(T obj) {
		Class<T> cls = (Class<T>) obj.getClass();
		LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
		try {
			Schema<T> schema = getSchema(cls);
			return ProtostuffIOUtil.toByteArray(obj, schema, buffer);//序列化
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(),e);
		} finally {
			buffer.clear();
		}
	}
	
	/**
	 * 反序列化（字节数组---》对象）
	 */
	public static <T> T deserialize(byte[] data,Class<T> cls) {
		try {
			T message = (T)objenesis.newInstance(cls);//实例化
			Schema<T> schema = getSchema(cls);//获取类的schema
			ProtostuffIOUtil.mergeFrom(data, message, schema);
			return message;
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(),e);
		}
	}
}
